package org.estela.ml.dataset;

import java.util.Arrays;
import java.util.logging.Logger;

import org.estela.stats.BasicStatistics;
import org.estela.stats.Frequencies;


/**
 *
 * @version 1.00
 * @date Apr 22, 2006
 * @author <a href="mailto:akantek@nyse.com">Antonio Kantek</a>
 */
public abstract class AbstractDataSet implements DataSet  {

	protected final Logger _log = Logger.getLogger(getClass().getName());
	
	/** */
	protected String name;

	/** */
	protected Attribute[] attributes;
	
	/** freqs for discrete attributes */
	protected Frequencies[] frequencies;
	
	/** stats for continuous attributes */
	protected BasicStatistics[] stats;	
	
	/** */
	protected int[] missingCounts;		
	
	/**
	 * Constructs a new <code>Instance</code>. 
	 */
	public AbstractDataSet() {
	}
	
	/**
	 * Constructs a new <code>Instance</code>. 
	 * @throws Exception 
	 */
	public AbstractDataSet(DataSetParser parser) throws Exception {
		this.name = parser.getDataSetName();
		this.attributes = parser.getAttributes();
		
		//move this code
		this.stats = new BasicStatistics[this.attributes.length];
		this.frequencies = new Frequencies[this.attributes.length];
		this.missingCounts = new int[attributes.length];
		Arrays.fill(this.missingCounts, 0);
		for(int i=0;i<attributes.length;i++) {
			if (attributes[i].isDiscrete()) {
				int numFrequencies = ((DiscreteAttribute) attributes[i]).getCategories().length;
				this.frequencies[i] = new Frequencies(numFrequencies);
			} else {
				this.stats[i] = new BasicStatistics();
			}
		}		
		
		Instance instance;
		while ((instance = parser.nextRow()) != null) {
			this.updateStats(instance);
		}
	}
	
	/*
	 * 
	 */
	public void updateStats(Instance instance) {
		for (int i = 0; i < this.attributes.length; i++) {
			if (this.attributes[i].isDiscrete()) {
				this.frequencies[i].addFrequency( (int) instance.getValueAt(i) );
			} else {
				this.stats[i].add( instance.getValueAt(i) );
			}
		}
	}	

	/**
	 * @return Returns the attributes.
	 */
	public Attribute[] getAttributes() {
		return attributes;
	}

	/**
	 * @return Returns the name.
	 */
	public String getName() {
		return name;
	}
	
	/*
	 *  (non-Javadoc)
	 * @see dataset.DataSet#getFrequencies(int)
	 */
	public Frequencies getFrequencies(int attributeIdx) {
		if (this.frequencies[attributeIdx] == null) {
			throw new IllegalArgumentException("Invalid attribute index: " + attributeIdx);
		}
		return this.frequencies[attributeIdx];
	}

	/*
	 *  (non-Javadoc)
	 * @see dataset.DataSet#getStats(int)
	 */
	public BasicStatistics getStats(int attributeIdx) {
		if (this.stats[attributeIdx] == null) {
			throw new IllegalArgumentException("Invalid attribute index: " + attributeIdx);
		}
		return this.stats[attributeIdx];
	}
	
	/*
	 *  (non-Javadoc)
	 * @see com.prototype.dataset.DataSet#missingCount(int)
	 */
	public int missingCount(int attributeIdx) {
		return this.missingCounts[attributeIdx];
	}	
}
